Draft: portable GGML GPU offload for Vulkan, Metal, and CUDA - #5
Draft
kenjorissen wants to merge 10 commits into
Draft
Draft: portable GGML GPU offload for Vulkan, Metal, and CUDA#5kenjorissen wants to merge 10 commits into
kenjorissen wants to merge 10 commits into
Conversation
validate-logits.py documented a C++ comparison but returned None without invoking the existing dump-logits binary. The binary also used std::partial_sort without including algorithm, which fails a clean GCC 15 build. Read dump-logits shape and float data, validate the serialized dimensions, and compare the result as documented. Cover the wrapper protocol with a deterministic stand-in executable, then exercise the real dump-logits binary and synthetic GGUF in the existing end-to-end test. Assisted-by: OpenAI Codex
Dream compares confidence across token positions after applying softmax. Raw logits are only comparable within one distribution: adding a position-specific constant preserves its probabilities while changing its raw-logit rank. Compute top-token probability, probability margin, and entropy from a numerically stable normalized distribution. Cover the regression with two rows whose raw-logit and probability-confidence orderings disagree. Assisted-by: OpenAI Codex
Dream shifts logits right, so row i predicts token position i + 1. The sparse active set retained a masked position but could cache the predecessor row that supplies its logits. Pass the model shift policy into active-set selection and retain those predecessor rows. Add a model-free CTest that distinguishes shifted and unshifted cache policies. Assisted-by: OpenAI Codex
generate.py removed one hard-coded LLaDA mask ID from every model output. Supported tokenizers can assign a different mask ID, leaving unresolved masks in decoded output or removing an unrelated token. Use tokenizer.mask_token_id when available and add model-free tests for tokenizer-specific and missing mask metadata. Assisted-by: OpenAI Codex
Assisted-by: OpenAI Codex
Assisted-by: OpenAI Codex
Allocate cached graphs through the selected GGML scheduler, transfer cached K/V state through backend tensors, and retain explicit placement checks. Cover full-cache extraction, active-set execution, quantized synthetic models, and cached generation. Assisted-by: OpenAI Codex
Run autoregressive prefill, decode, batch, profiling, and speculative graphs through the selected GGML backend. Add CPU/device parity coverage and expose a bounded tolerance for quantized backend comparisons. Assisted-by: OpenAI Codex
Assisted-by: OpenAI Codex
Pass exact GGML device names through generation and logit-validation wrappers, and exercise device-aware logit dumping in the synthetic end-to-end test. Assisted-by: OpenAI Codex
kenjorissen
force-pushed
the
integration/portable-gpu-offload
branch
from
August 18, 2026 14:54
2090531 to
247386f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Status
This is an integration-preview draft, not a request to merge the entire series
as one change. It publishes the complete tested implementation for users and
invites guidance on the proposed review split below.
The branch keeps CPU execution available and adds exact GGML device selection,
integrated-GPU acceptance, direct backend weight loading, and scheduled graph
execution for Vulkan, Metal, and CUDA. It covers full and cached masked
diffusion as well as autoregressive prefill, decode, batch, profiling, and
speculative decoding.
Commit structure
The history is intentionally linear and each commit builds and passes its
applicable model-free tests:
The four pre-existing bug fixes are kept free of GPU behavior. The first is
also proposed independently in #4. Standalone branches for the remaining fixes
are available in the fork but have not been opened as additional upstream PRs:
fix/dream-probability-rankingfix/dream-shifted-cachefix/tokenizer-mask-idPlacement and backend coverage
The implementation uses GGML's device, buffer, and scheduler abstractions; it
contains no product-specific Strix Halo, Apple, or NVIDIA path. The CLI accepts
an exact device name and reports both model allocation and per-backend graph
node counts. A selected non-CPU device fails visibly if the scheduler places no
operations on it.
The cleaned tip has been freshly built and tested on:
Vulkan01180, cached1236, CPU0MTL01180, cached1236, CPU0CUDA01180, cached1236, AR872, CPU0The cleaned tip was validated through
CUDA0using CUDA 13.3 Update 1. Theexact prior history remains available as
archive/portable-gpu-offload-validated-3774fc6.Validation
order with GCC 15.2 and
GGML_NATIVE=OFF;-Wall -Wextra -Wpedantic -WerrorCPU builds;cache, autoregressive prefill/decode/batch/profiling, high-level generation,
and speculative decoding on
Vulkan0,MTL0, andCUDA0; quantized ARrequires exact greedy-token equality while allowing
0.003NMSE forbackend-specific quantized reductions;
selected backend and executes full and cached production graphs with no
observed CPU nodes on all three freshly tested GPUs;
0.000072243on Vulkan and0.000063916on Metal, and0.000078607on CUDA; andregressions are part of CTest.
The previously recorded matched cache-on throughput was:
CUDA no-cache reached 155.36 tok/s. These are runtime comparisons on different
hosts, not controlled GPU rankings, and were not rerun merely to reconstruct
the commit history.
Known numerical limitation
The production sparse active-set graph is shape- and backend-sensitive. In the
four-row diagnostic, logit NMSE is
0.0425762on Vulkan,0.0188916onMetal, and
0.0505584on CUDA even though K/V remains close.Top-token mismatches also vary by backend and shape.
The production Dream AR diagnostic places all
872graph nodes on CUDA, butits greedy sequence does not exactly match CPU. The generated two-layer Q4_K_M
AR test does match CPU exactly. Production AR placement is therefore evidence
of execution coverage, not a language-output parity claim.
A decoded arithmetic control returned
345on CPU, Metal cache/no-cache, andVulkan no-cache, but default Vulkan sparse cache returned
355. This drafttherefore does not claim language-output parity.
--no-cacheis the currentcorrectness-sensitive control until a prompt corpus measures the approximation.
On the tested CUDA workload it was also faster than sparse caching.
Proposed review split
If there is maintainer interest, I would turn the GPU portion into three
stacked review units rather than request review of this complete integration
diff:
The focused correctness fixes can continue independently of that series.
AI assistance disclosure
I used OpenAI Codex to help investigate the defects, implement the changes,
construct the tests, and organize the commit series. I reviewed the resulting
diffs and validation output and take responsibility for the contribution.